// Fill out your copyright notice in the Description page of Project Settings.

#include "SpaceFortress.h"
#include "Empire.h"
#include "Utility.h"
#include "Market/Comodities.h"

AEmpire::AEmpire(const FObjectInitializer& OI)
	: Super(OI)
{
	marketDuration = 10;
	currTime = 0;
}

void AEmpire::Initialize()
{
	OpenVector<uint32> comodities;
	building_manager.Initialize(comodities);
	comodity_manager.Initialize(comodities);
}

void AEmpire::Tick(float DeltaSeconds)
{
	if (!marketDuration) {
		return;
	}

	currTime += DeltaSeconds;
	if (currTime >= marketDuration) {
		currTime -= marketDuration;

		building_manager.RunProduction();

		// Process the market turn.
		BidData* buy_data = NULL;
		comodity_manager.InitializeBuyData(buy_data);

		BidData* sell_data = NULL;
		comodity_manager.InitializeSellData(sell_data);

		building_manager.PlaceMarketOrders(buy_data, sell_data);

		comodity_manager.ReCalculateSupply(sell_data);
		comodity_manager.ReCalculateDemand(buy_data);

		// Handle all of the market orders.
		for (uint32 i = 0; i < comodity_manager.GetNumResources(); i++) {
			comodity_manager.SortBuyData(buy_data[i], 0, buy_data[i].size - 1);
			comodity_manager.SortSellData(sell_data[i], 0, sell_data[i].size);
		}

		comodity_manager.ResolveSales(buy_data, sell_data);

		/*
			Do we need to seperate consumption bids from input bids? I don't think its necessary.
		*/
		building_manager.ProcessMarketResults(buy_data, buy_data, sell_data, comodity_manager.GetComodityMeans(),
			comodity_manager.GetComoditySupply(), comodity_manager.GetComodityDemand(), comodity_manager.GetNumResources());

		delete[] buy_data;
		delete[] sell_data;

		// Map the comodity index to the number of buyers and sellers being removed for each type.
		OpenMap<uint32, uint32> buyers;
		OpenMap<uint32, uint32> sellers;
		building_manager.ProcessDefunctEntities(buyers, sellers);
		comodity_manager.DeregisterBuyers(buyers);
		comodity_manager.DeregisterSellers(sellers);

		/*
			For later on.
			The planet will loop through each district and determine what it can create
			Then these possibilities (for each district) will be handed off to the comodity manager
			which will determine which one (for each district) has the highest sale price.
			Then the allocation will be called for each district with the type chosen for that district.

			If I'm not mistaken this should be the only place where district resource and production modifications
			should come into play.
		*/
		buyers.Clear();
		sellers.Clear();
		building_manager.AllocateNewProduction(comodity_manager.GetComodityMeans(), 
			comodity_manager.DetermineFactoryType(), buyers, sellers);
		comodity_manager.RegisterBuyers(buyers);
		comodity_manager.RegisterSellers(sellers);
	}
}

